package scheduler

import (
	"fmt"
	"github.com/hibiken/asynq"
	"go-zero-admin/application/job/rpc/internal/model"
	"log"
	"strconv"
	"time"
)

func (l *TaskScheduler) taskSchedule() { //从数据库中获取所有任务

	defer func() { //防止panic退出监听
		if r := recover(); r != nil {
			log.Println(r)
		}
	}()

	for _, task := range TaskList {
		switch task.TaskType {
		case "0":
			l.timedToopTask(task) //定时循环任务
		case "1":
			l.onceTask(task) //一次性任务
		case "2":
			l.onceAsyncTask(task) //一次性任务延迟执行
		case "3":
			l.onceTimedTask(task) //一次性任务指定时间运行
		default:
			log.Println("任务类型不正确")
		}
	}
}

// 定时循环任务
func (l *TaskScheduler) timedToopTask(task model.TaskSchedule) {
	fmt.Println(fmt.Sprintf("注册定时循环任务:%+v", task))
	if !l.canRun(task.UniqueID) {
		return
	}
	t := asynq.NewTask(task.UniqueID, []byte(task.ExecCmd))
	_, err := l.svcCtx.AsynqScheduler.Register(task.TimeSchedule, t, uniqueTaskId(task.UniqueID), asynq.MaxRetry(int(task.MaxRetry)))
	if err != nil {
		log.Println(fmt.Sprintf("任务注册出错:%s", err))
	}
	sLog("timedToopTask", err)

}

// 一次性任务
func (l *TaskScheduler) onceTask(task model.TaskSchedule) {
	fmt.Println(fmt.Sprintf("注册一次性任务:%+v", task))
	if !l.canRun(task.UniqueID) {
		return
	}

	t := asynq.NewTask(task.UniqueID, []byte(task.ExecCmd))
	_, err := l.svcCtx.AsynqClient.Enqueue(t, uniqueTaskId(task.UniqueID), asynq.MaxRetry(int(task.MaxRetry)))
	if err != nil {
		log.Println(fmt.Sprintf("任务注册出错:%s", err))
	}
	sLog("onceTask", err)
}

// 一次性任务延迟执行
func (l *TaskScheduler) onceAsyncTask(task model.TaskSchedule) {
	fmt.Println(fmt.Sprintf("注册一次性任务延迟执行:%+v", task))
	if !l.canRun(task.UniqueID) {
		return
	}
	t := asynq.NewTask(task.UniqueID, []byte(task.ExecCmd))
	duTime, err := strconv.Atoi(task.TimeSchedule)
	if err != nil {
		return
	}
	_, err = l.svcCtx.AsynqClient.Enqueue(t, uniqueTaskId(task.UniqueID), asynq.ProcessIn(time.Duration(duTime)))
	if err != nil {
		log.Println(fmt.Sprintf("任务注册出错:%s", err))
	}
	sLog("onceAsyncTask", err)
}

// 一次性任务指定时间运行
func (l *TaskScheduler) onceTimedTask(task model.TaskSchedule) {
	fmt.Println(fmt.Sprintf("注册一次性任务指定时间运行:%+v", task))
	if !l.canRun(task.UniqueID) {
		return
	}
	t := asynq.NewTask(task.UniqueID, []byte(task.ExecCmd))

	duTime, err := strconv.Atoi(task.TimeSchedule)
	if err != nil {
		return
	}
	_, err = l.svcCtx.AsynqClient.Enqueue(t, uniqueTaskId(task.UniqueID), asynq.ProcessAt(time.Unix(int64(duTime), 0)))
	if err != nil {
		log.Println(fmt.Sprintf("任务注册出错:%s", err))
	}
	sLog("onceTimedTask", err)
}
